package org.hs.phd.odi.tracking.tracker.particlefilter.tracker;

import org.hs.phd.odi.tracking.tracker.Histogram;
import org.hs.phd.odi.tracking.tracker.TrackWindow;
import org.hs.phd.odi.tracking.tracker.particlefilter.core.Particle;
import org.hs.phd.odi.tracking.tracker.particlefilter.core.ParticleFilter;
import org.hs.phd.odi.tracking.tracker.particlefilter.observation.HistogramMatchingObservationModel;
import org.hs.phd.odi.tracking.tracker.particlefilter.resampling.ImportanceResamplingStrategy;
import org.hs.phd.odi.tracking.tracker.particlefilter.state.SphericalWindowParticleState;
import org.hs.phd.odi.tracking.tracker.particlefilter.transition.SphericalWindowAutoRegressiveDynamicsTransitionModel;
import org.hs.phd.odi.tracking.tracker.trackwindow.ODIOnTheSphereTrackWindow;
import org.hs.phd.odi.transformation.ODITransformation;

import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class SphericalHistogramMatchingBasedParticleFilterTracker extends AbstractSingleObjectParticleFilterTracker<SphericalWindowParticleState> {

	private static final int NUMBER_OF_PARTICLES = 50;

	public SphericalHistogramMatchingBasedParticleFilterTracker(ODITransformation transformation){
		super( new ODIOnTheSphereTrackWindow(transformation) );
	}
	

	@Override
	protected Particle<SphericalWindowParticleState> createInitialParticle(TrackWindow trackWindow) {
		ODIOnTheSphereTrackWindow odiWindow = (ODIOnTheSphereTrackWindow) trackWindow;
		SphericalWindowParticleState initialState = 
				new SphericalWindowParticleState(odiWindow.getTheta(), odiWindow.getPhi(), odiWindow.getDeltaTheta(), odiWindow.getDeltaPhi());
		
		return new Particle<SphericalWindowParticleState>(1, initialState);
	}

	@Override
	protected ParticleFilter<SphericalWindowParticleState> createParticleFilter(IplImage initialFrame, Histogram targetHistogram, TrackWindow trackWindow) {
		ParticleFilter<SphericalWindowParticleState> filter = new ParticleFilter<SphericalWindowParticleState>(NUMBER_OF_PARTICLES, 
				//new NULLTransitionModel(),
				new SphericalWindowAutoRegressiveDynamicsTransitionModel(),
				new HistogramMatchingObservationModel<SphericalWindowParticleState>(targetHistogram, trackWindow, this),
				new ImportanceResamplingStrategy<SphericalWindowParticleState>());
		filter.setDebugEnabled(true);
		return filter;
	}


	@Override
	public void updateTrackWindowUsingParticleState(TrackWindow trackWindow, SphericalWindowParticleState particleState) {
		ODIOnTheSphereTrackWindow odiWindow = (ODIOnTheSphereTrackWindow) trackWindow;
		odiWindow.set(particleState.theta, particleState.phi, particleState.scale*particleState.deltaTheta, particleState.scale*particleState.deltaPhi);
	}

	@Override
	public String getName() {
		return "Spherical Histogram Based Particle Filter Tracker";
	}


}
